/**
 * new的过程文字描述：
1.创建一个空对象 obj;
2.将空对象的隐式原型（proto）指向构造函数的prototype。
3.使用 call 改变 this 的指向
4.如果无返回值或者返回一个非对象值，则将 obj 返回作为新对象；如果返回值是一个新对象的话那么直接直接返回该对象。
new 关键词执行之后总是会返回一个对象，要么是实例对象，要么是 return 语句指定的对象。 
*/

function Person(name, age) {
  this.name = name
  this.age = age
}
Person.prototype.sayHi = function () {
  console.log('Hi！我是' + this.name)
}

function create() {
  // 创建空对象
  let obj = {}
  // 隐式原型
  // 处理参数列表。参数列表包含了类和构造函数的参数
  const args = [...arguments]
  let fn = args.shift()
  // 将空对象的隐式原型（proto）指向构造函数的prototype。
  obj.__proto__ = fn.prototype
  // 通过call改变this的指向
  let result = fn.call(obj, args)
  // 返回
  return typeof result === 'object' ? result : obj
}
let p2 = create(Person, '李四', 19)
p2.sayHi()